【X68000(Z)アセンブラ講座 第005回 第004回のサンプルの詳細説明@】2025/01/07   今回は第004回のサンプルプログラムを理解して吸収できるようになるために 必要な情報を書いていく事にします。 -------------------------------------------------------------------------------- 【 数値の扱いについて 】 数値データを扱うには数値の前に'#'を付けます。 ('#'を付けない場合は数値はアクセスするアドレスを直接指定した事になります。) 数値を16進数で表現したい場合は数値の前に'$'を付けます。 move.l #$E00000,a0 数値を2進数で表現したい場合は数値の前に'%'を付けます。 2進数表記の中に見やすくするために区切り記号'_'を入れる事ができます。 move.w #%11111_11111_11111_0,d0 '#'を付けないと数値をアドレスを直接指定した事になります。 move.w $2000,d0 * アドレス$2000からワードサイズでd0にデータをコピーします。 move.w d0,$2000 * アドレス$2000にd0の値をコピーします。 -------------------------------------------------------------------------------- 【 ラベル 】 start: moveq.l #_B_SUPER,d0 * d0にIOCS(BIOS)機能番号を代入 move.l #0,d1 * 数値0をd1に代入 movea.l d1,a1 * d1をa1にコピー trap #15 * IOCSコール実行  ↑の例は'start'+':'でラベルと呼ばれるものになります。 ラベルはデータアクセスしたりジャンプ先にしたりサブルーチンの名前にしたりして、 プログラム内のアドレス計算をアセンブラがソフト内のアドレス値を自動的に計算して プログラミングが楽になるようになっています。 同じラベルを記述するとエラーになります。 -------------------------------------------------------------------------------- 【 MC68000のデータのサイズとデータアクセス 】 MC68000のメモリーアクセスのデータサイズには、 ・8ビット('.b':バイト) 1バイト ・16ビット('.w':ワード) 2バイト ・32ビット('.l':ロングワード) 4バイト これらの3種類が用意されています。 MC68000のデータレジスター(ハードウェアCPU変数)のサイズは '.b'と'.w'と'.l'の3つが用意されています。 例としてd0内のの16ビット(2バイト)データをa0内の数値が示すアドレスに書き込むには、 move.w d0,(a0)  ↑のように命令を記述します move.w d1,(a2)+  ↑の命令はa2が示すアドレスにd1の16ビットデータを書き込んだ後にa2に2を足します move.l -(a1),d7  ↑の命令はa1から4を引いた後にa1が示すアドレスの32ビットデータをd7に読み込みます move.w 2(a0),d0  ↑の命令はa0に2を足したアドレスから16ビットデータをd0に読み込みます アドレスレジスターにアドレスを入れるにはmovea命令を使います。 movea.l #$C00000,a0 * CG-VRAMの先頭アドレスをa0に代入します。 move系の命令は、命令の後に二つのパラメータ(オペランド)が必要で、 左側のオペランドがオペランド1で右側のオペランドがオペランド2とすると データはオペランド1からオペランド2へコピーされます。 -------------------------------------------------------------------------------- 【 メモリー確保 : dcとds 】 dcはプログラム起動時にメモリー上に確保するメモリーです。 .data width: dc.b 100 * 1byteのメモリーを確保して初期値100を入れておく str00: dc.b 'X680x0(Z)' * 文字数分のバイト数を確保して初期値'X680x0(Z)'内のそれぞれのキャラクターコードを入れておく str01: dc.b 'X680x0(Z)',0 * 文字数分のバイト数と1byteデータ('0')を足したサイズ確保して初期値'X680x0(Z)'+1byte内のそれぞれのキャラクターコードを入れておく .even num: dc.w 12345 * 2byteのメモリーを確保して初期値12345を入れておく stage: dc.l 10 * 4byteのメモリーを確保して初期値10を入れておく dsはプログラム起動時にメモリー上に初期値無しで確保するメモリーです。 .bss buf00: ds.b 32 * バイトデータ領域を32個確保する buf01: ds.w 1024 * ワードデータ領域を1024個確保する buf02: ds.l 8 * ロングデータ領域を8個確保する -------------------------------------------------------------------------------- 【 PC : プログラムカウンター 】 PC(プログラムカウンター)は現在実行中の命令のアドレスが格納される。 -------------------------------------------------------------------------------- 【 無条件分岐 】 [ JMP命令 ] jmp L0000  ↑ラベルL0000へ飛ぶ [ JSR命令 ] jsr L0001  ↑ラベルL0001のサブルーチンをコールする [ BRA命令 ] bra L0002  ↑ラベルL0000へ飛ぶ JMP命令より速いがコールはレジスターPCから+-32KBの範囲内のアドレスに限る [ BSR命令 ] bsr L0003  ↑ラベルL0003のサブルーチンをコールする JSR命令より速いがコールはレジスターPCから+-32KBの範囲内のアドレスに限る -------------------------------------------------------------------------------- 【 条件分岐 】 比較命令CMP等の結果によって条件分岐するかしないか決定。 (CMPの比較結果の出し方はオペランド2からオペランド1を引いた結果をccrに反映させる) [ BLT命令 ] Branch Less Than cmp.w #768,d0 blt L1000 ↑比較結果が768未満ならL1000へ飛ぶ [ BLE命令 ] cmp.w #100,d1 blt L1001 ↑比較結果が100以下ならL1001へ飛ぶ [ BGT命令 ] cmp.w #256,d2 bgt L1002 ↑比較結果が256より大きいならL1002へ飛ぶ [ BGE命令 ] cmp.l #65536,d3 bge L1003 ↑比較結果が65536以上ならL1003へ飛ぶ [ BEQ命令 ] cmp.w #384,d4 beq L1004 ↑比較結果が0なら(同じなら)L1004へ飛ぶ [ BNE命令 ] cmp.w #100,d5 bne L1005 ↑比較結果が0以外なら(異なるなら)L005へ飛ぶ [ BPL命令 ] cmp.w #1000,d6 bpl L1006 ↑比較結果がプラスならL1006へ飛ぶ [ BMI命令 ] cmp.l #10,d7 bmi L1007 ↑比較結果がマイナスならL1007へ飛ぶ -------------------------------------------------------------------------------- 【 ビットシフト / ローテート 】 [ LSR命令(ビットシフト) ] ビットデータを指定ビット数分右へシフトします。 lsr.w #3,d0 ↑d0の中身を3ビット右へシフトします。 [ LSL命令(ビットシフト) ] ビットデータを指定ビット数分左へシフトします。 lsL.w #5,d0 ↑d0の中身を5ビット左へシフトします。 [ ROR命令(ローテート) ] ビットデータを指定ビット数分右へシフトします。 それと同時にシフトして出て行ったビットデータは左から入ってきます。 ror.w #8,d0 ↑d0の中身を8ビット右へローテートします。 ワードサイズで右へ8ビットローテートすると上下バイトが逆になるのでIntel対策にも使えます。 [ ROL命令(ローテート) ] ROL命令はRORと逆の左側へのローテートを行います rol.w #8,d0 ↑d0の中身を8ビット左へローテートします ワードサイズで左へ8ビットローテートすると上下バイトが逆になるのでIntel対策にも使えます -------------------------------------------------------------------------------- 【 論理演算 】 [ AND/ANDI命令 ] 2進数で考えた方が楽です。 レジスターに入っている数値データの中から必要な部分のビットだけを取り出す(マスクする)。 move.b (a0)+,d0 andi.b #%00001111,d0 ↑d0の1のマスクビット以外のビットをd0の中で0にする。 オペランド1が数値指定以外の時はANDを使用して下さい。 [ OR/ORI命令 ] 2進数で考えた方が楽です。 オペランド1の中のビット1のデータをオペランド2に重ね合わせて合成する。 move.w #%10100000_11001100,d0 ori.w #%00001111_00110000,d0 ↑の結果は'10101111_11111100'になります。 オペランド1が数値指定以外の時はORを使用して下さい。 -------------------------------------------------------------------------------- 68000初心者向け推奨参考サイト↓ https://www.kkaneko.jp/cc/as/advanced/outline.html -------------------------------------------------------------------------------- サンプルプログラム中のコメントだけでは説明が足りないと思ったので 今回はサンプルプログラムを理解できるように沢山のキーワードと答えを書いたつもりですが、 もし説明が抜けている部分があったらコメントでお知らせ下さい。 ご健闘を御祈り致します!!(^^v [EOF]